package com.gjs.management.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Validator;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gjs.common.enums.entity.StatusEnum;
import com.gjs.common.exception.BizException;
import com.gjs.common.manager.response.RspBody;
import com.gjs.common.manager.sso.SsoClient;
import com.gjs.common.microservice.api.IUserMicroService;
import com.gjs.common.pojo.dto.request.PageQuery;
import com.gjs.common.pojo.dto.response.ListPageRsp;
import com.gjs.common.pojo.dto.user.UserInfoDTO;
import com.gjs.common.pojo.dto.user.UserQueryDTO;
import com.gjs.management.pojo.dto.staff.StaffQueryDTO;
import com.gjs.management.pojo.entity.ManagementStaff;
import com.gjs.management.pojo.vo.role.SysRoleRspVO;
import com.gjs.management.pojo.vo.staff.ManagementStaffReqVO;
import com.gjs.management.pojo.vo.staff.ManagementStaffRspVO;
import com.gjs.management.service.IManagementStaffService;
import com.gjs.management.service.ISysRoleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

@RestController
@Slf4j
@Api(tags = "员工接口")
@RequiredArgsConstructor
@RequestMapping("/staff")
public class StaffController {

    @Value("${jwt.management.cache-key}")
    private String cacheKey;

    private final IManagementStaffService managementStaffService;

    private final SsoClient ssoClient;

    private final RedisOperations<String, Object> redisUtil;

    @DubboReference
    private IUserMicroService userMicroService;

    private final ISysRoleService sysRoleService;

    @GetMapping("/get_authorize_url")
    @ApiOperation("SSO登录链接")
    public RspBody<String> getAuthorizeUrl() {
        return RspBody.success(ssoClient.buildAuthorizeUrl(UUID.randomUUID().toString(), "all"));
    }

    @GetMapping("/logout")
    @ApiOperation("登出")
    public RspBody<String> logout() {
        redisUtil.delete(cacheKey + managementStaffService.getUserBySecurity().getUserSn());
        return RspBody.success("成功");
    }

    @GetMapping("/get_info")
    @ApiOperation("获取人员信息")
    public RspBody<UserInfoDTO> getInfo() {
        return RspBody.success(managementStaffService.getUserBySecurity());
    }

    @GetMapping("/get_permission")
    @ApiOperation("获取权限")
    public RspBody<Set<String>> getPermission() {
        return RspBody.success(AuthorityUtils.authorityListToSet(managementStaffService.getPermissionBySecurity()));
    }

    @GetMapping("/list")
    @ApiOperation("员工列表")
    public RspBody<ListPageRsp<ManagementStaffRspVO>> list(StaffQueryDTO staffQueryDTO, PageQuery pageQuery) {
        IPage<ManagementStaff> managementStaffIPage = managementStaffService.page(pageQuery.buildPage(), managementStaffService.buildWrapper(staffQueryDTO));
        Map<String, UserInfoDTO> userInfoMap = new HashMap<>();
        if (!managementStaffIPage.getRecords().isEmpty()) {
            // 获取员工关联的用户信息
            Set<String> userSnSet = managementStaffIPage.getRecords().stream().map(ManagementStaff::getUserSn).collect(Collectors.toSet());
            UserQueryDTO userQueryDTO = new UserQueryDTO();
            userQueryDTO.setUserSnSet(userSnSet);
            List<UserInfoDTO> userInfoList = userMicroService.list(userQueryDTO);
            userInfoMap = userInfoList.stream().collect(Collectors.toMap(UserInfoDTO::getUserSn, UserInfoDTO -> UserInfoDTO));
        }

        ListPageRsp<ManagementStaffRspVO> listPageRsp = ListPageRsp.of(managementStaffIPage, ManagementStaffRspVO.class);

        if (!userInfoMap.isEmpty()) {
            for (int i = 0; i < listPageRsp.getRecords().size(); i++) {
                ManagementStaffRspVO managementStaffRspVO = (ManagementStaffRspVO) listPageRsp.getRecords().get(i);
                if (userInfoMap.containsKey(managementStaffRspVO.getUserSn())) {
                    managementStaffRspVO.setUserInfo(userInfoMap.get(managementStaffRspVO.getUserSn()));
                }
            }
        }

        return RspBody.success(listPageRsp);
    }


    @GetMapping("/detail")
    @ApiOperation("角色详情")
    public RspBody<ManagementStaffRspVO> detail(Long id) {
        ManagementStaff staff = managementStaffService.getById(id);
        if (staff == null) {
            throw new BizException("找不到该员工");
        }

        return RspBody.success(managementStaffService.getManagementStaffRspVO(staff));
    }

    @GetMapping("/role_selector")
    @ApiOperation("角色映射表")
    public RspBody<List<SysRoleRspVO>> roleSelector(){
        List<SysRoleRspVO> sysRoleRspVOList = sysRoleService.list()
                .stream()
                .map(row -> BeanUtil.copyProperties(row,SysRoleRspVO.class))
                .collect(Collectors.toList());
        return RspBody.success(sysRoleRspVOList);
    }

    @PostMapping("/add")
    @ApiOperation("添加")
    @Transactional
    public RspBody<ManagementStaffRspVO> add(@RequestBody Map<String, String> params) {
        String mobile = params.get("mobile");
        if (!Validator.isMobile(mobile)) {
            throw new BizException("无效手机号");
        }

        UserQueryDTO userQueryDTO = new UserQueryDTO();
        userQueryDTO.setMobile(mobile);
        UserInfoDTO userInfoDTO = userMicroService.getOne(userQueryDTO);
        if (userInfoDTO == null) {
            throw new BizException("用户不存在或未注册");
        }

        ManagementStaff staff = new ManagementStaff();
        try {
            staff.setUserSn(userInfoDTO.getUserSn());
            staff.setStatus(StatusEnum.ENABLE); // 新添加的员工默认可用
            // 添加员工
            managementStaffService.save(staff);
        } catch (Exception e) {
            throw new BizException("添加员工失败：" + e.getMessage());
        }

        return RspBody.success(BeanUtil.copyProperties(staff, ManagementStaffRspVO.class));
    }

    @PostMapping("/update")
    @ApiOperation("更新")
    @Transactional
    public RspBody<ManagementStaffRspVO> update(@RequestBody ManagementStaffReqVO vo) {
        try {
            managementStaffService.updateRole(vo);
        } catch (Exception e) {
            throw new BizException("更新角色失败：" + e.getMessage());
        }

        return RspBody.success(managementStaffService.getManagementStaffRspVO(managementStaffService.getById(vo.getId())));
    }
}
